/*
 * TimeIncrementCalculationStrategy.h
 *
 *  Created on: 02/10/2011
 *      Author: godinho
 */

#ifndef TIMEINCREMENTCALCULATIONSTRATEGY_H_
#define TIMEINCREMENTCALCULATIONSTRATEGY_H_

#include <pthread.h>

namespace localview {
class LocalView;
}

class Case;

/**
 * This class declares a common interface for all strategies to calculate
 * green extensions for phases of a Traffic light controller. Also, is
 * defined here a set of methods to make easy execution of these algorithms
 * on threads.
 */
class TimeIncrementCalculationStrategy {
public:
	TimeIncrementCalculationStrategy();
	virtual ~TimeIncrementCalculationStrategy();

	/**
	 * Start this algorithm in a new thread.
	 */
	void start(localview::LocalView* lv, int phaseId, int timestep);

	/**
	 * Stop algorithm execution.
	 *
	 * This method can be called only after a call to {@link TimeIncrementCalculationStrategy::start()}
	 *
	 * WARNING: this method should not be called from the worker thread.
	 */
	void stop();

	/**
	 * This method are used on assynchronous execution to retrieve
	 * calculation result.
	 *
	 * This method can be called only after a call to the following methods
	 * (on the order presented):
	 *
	 * <ul>
	 * 	<li>{@link TimeIncrementCalculationStrategy::start()}</li>
	 * 	<li>{@link TimeIncrementCalculationStrategy::stop()}</li>
	 * </ul>
	 *
	 * If neither of this method was called, an exception is thrown.
	 *
	 * @return green increment calculated on the last execution of algorithm
	 */
	Case* getResult();

	/**
	 * This method must be implemented with the logic used to calculate gree
	 * extension values.
	 *
	 * @param LocalView is the context used as input of increment algorithm
	 * @param phaseId number that identifies a phase
	 * @return green increment
	 */
	virtual Case* run(localview::LocalView* lv, int phaseId, int timestep) = 0;

	/**
	 * Method called when the calculation stops.
	 */
	virtual void onStop() = 0;

	localview::LocalView* getLocalView();

	int getPhaseId();

	void setResult(Case* value);

	int getTimestep();

protected:

	/**
	 * This method returns true to indicates that stop method was called
	 * allowing algorithim called in run to stop its execution.
	 *
	 * @return true indicating that algorithm must stop.
	 */
	bool isInterrupted();

private:
	pthread_t mThreadId;

	pthread_attr_t mThreadAttrs;

	pthread_mutex_t mIsInterruptedMutex;

	localview::LocalView* mLocalView;

	int mPhaseId;

	int mTimestep;

	bool mIsInterrupted;

	Case* mResult;
};

#endif /* TIMEINCREMENTCALCULATIONSTRATEGY_H_ */
